#include "stdafx.h"
#include "RMSHostEnt.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

//#define mydebug

#ifdef mydebug
#include <string>
using namespace std;
class CMyDebug { public:
  FILE* flog;LARGE_INTEGER fq,ct;
  CMyDebug(string fname) {flog = fopen(fname.c_str(), "wt");QueryPerformanceFrequency(&fq);};
  string inttostr(int n){char buf[32]; sprintf(buf, "%d", n); return string(buf);}
  void printsome(string title, unsigned char* buf, int n, int atmost) {
    int i; unsigned char c; if (atmost<n) n=atmost; fprintf(flog,"%s: ",title.c_str());
    for(i=0; i<n; i++) fprintf(flog,"%4d", buf[i]); fprintf(flog," (");
    for(i=0; i<n; i++) {c=buf[i]; if (c<32) c='_'; fprintf(flog,"%c",c);}
    fprintf(flog,")\n"); fflush(flog);};
  void printstr(string s) {fprintf(flog,"%s\n",s.c_str());fflush(flog);}
  void printstr0(string s) {fprintf(flog,"%s",s.c_str());fflush(flog);}
  void printint(int x) {fprintf(flog,"%u\n",x);fflush(flog);}
  void printstrint(string s, int x) {fprintf(flog,"%s: %u\n", s.c_str(), x);fflush(flog);}
  string tsc4(){QueryPerformanceCounter(&ct);char bb[16];sprintf(bb,"%5.3f",((ct.QuadPart*1000/fq.QuadPart)%10000)/1000.0);return bb;};
  int readmsec(){QueryPerformanceCounter(&ct);return (int)(ct.QuadPart*1000/fq.QuadPart);};
  ~CMyDebug(){fclose(flog);};
};CMyDebug md5("debug.log");
#endif


RMSHostEnt::RMSHostEnt():
	m_dwDefaultIP(INADDR_ANY)
{
	
	gethostname(m_cbHostName,HOSTNAME_LEN);
	m_host = gethostbyname(m_cbHostName);

	// fill m_iparr
	if(m_host)
	{
		int i = 0;
        m_iparr.insert(IPArr::value_type( 0, "0.0.0.0"));
 		while(m_host->h_addr_list[i])
		{
			DWORD dwIP = *(DWORD*)(m_host->h_addr_list[i]);
			String str;
			GetIPString(str, dwIP);
#ifdef mydebug
char buf[256]; sprintf(buf, "%d. %s",i, str.c_str());
md5.printstr(buf);
#endif

			m_iparr.insert(IPArr::value_type( dwIP, str));
			//m_iparr.push_back(dwIP);
			++i;
		}
	}

	SetDefaultIP(0);
}

RMSHostEnt::~RMSHostEnt()
{
}


DWORD RMSHostEnt::DefaultIP() const
{
	return m_dwDefaultIP;
}

bool RMSHostEnt::DefaultIP(DWORD dwNewIP)
{
	if(SetDefaultIP(dwNewIP))
	{
		return true;
	}

	return false;
}

bool RMSHostEnt::IsHostIP(DWORD dwIP) const
{
	/*
	for(i=0; i < m_iparr.size(); i++)
	{
		if(m_iparr[i] == dwIP)
		{
			return true;
		}
	}*/
	IPArr::const_iterator it = m_iparr.find(dwIP);
	if(it != m_iparr.end())
	{
		return true;
	}

	return false;
}

// local ip = 192.168.
bool RMSHostEnt::IsLocalIP(DWORD dwIP)
{
	if((dwIP & 0xFFFF) == (192+168*256)) 
	{
		return true;
	}

	if(((dwIP & 0xFF00) < 32*256) && ((dwIP & 0xFF00) >= 16*256) && ((dwIP & 0xFF) == 172))
	{
		return true;
	}

	if((dwIP & 0xFF) == 10)
	{
		return true;
	}

	return false;
}


// localhost ip = 127.0.0.1
bool RMSHostEnt::IsLocalHostIP(DWORD dwIP)
{
	return (dwIP == 0x0100007F);
}

void RMSHostEnt::setAddrAnyIP()
{
	m_dwDefaultIP = ADDR_ANY;
}

bool RMSHostEnt::SetDefaultIP(DWORD dwNewIP) 
{
#ifdef mydebug
char buf[128]; sprintf(buf, "SetDefaultIP(%d)",dwNewIP);
md5.printstr(buf);
#endif
	if(IsHostIP(dwNewIP) && !IsLocalIP(dwNewIP))
	{
#ifdef mydebug
md5.printstr("IsHostIP and not IsLocalIP");
#endif
		m_dwDefaultIP = dwNewIP;
		return true;
	}

	if(IsLocalIP(dwNewIP))
	{
#ifdef mydebug
md5.printstr("IsLocalIP");
#endif
        if(IsHostIP(dwNewIP))
          m_dwDefaultIP = dwNewIP;
        else
  		  m_dwDefaultIP = GetValidIP();
		return true;
	}
	m_dwDefaultIP = GetValidIP();
#ifdef mydebug
sprintf(buf, "GetValidIP: %d", m_dwDefaultIP);
md5.printstr(buf);
#endif
	return true;
}

void RMSHostEnt::DefaultIPString(String& str) const
{
	GetIPString(str, m_dwDefaultIP);
}

DWORD RMSHostEnt::GetValidIP() const
{
	IPArr::const_iterator it = m_iparr.begin();
	while(it != m_iparr.end())
	{
		DWORD ip = (*it).first;
		if(!IsLocalIP(ip))
		{
			return ip;
		}
		++it;
	}

	it = m_iparr.begin();
	while(it != m_iparr.end())
	{
		DWORD ip = (*it).first;
		if(!IsLocalHostIP(ip))
		{
			return ip;
		}
		++it;
	}

	return INADDR_ANY;
}

CString RMSHostEnt::getAllHomeIPs()
{
	CString tmp;
	CString res = _T("");
	IPArr::const_iterator it = m_iparr.begin();
	while(it != m_iparr.end())
	{
		if(!res.IsEmpty())
			res += _T("\n");
		GetIPString(tmp, (*it).first);
		res += tmp;
		++it;
	}
	return res;
}

void RMSHostEnt::GetIPString(String& str, DWORD dwIP)
{
	char name[100];
	sprintf(name,"%d.%d.%d.%d",dwIP&255,(dwIP>>8)&255,(dwIP>>16)&255,(dwIP>>24)&255);
	str = name;
}

void RMSHostEnt::GetIPString(CString& str, DWORD dwIP)
{
	char name[100];
	str.Format(_T("%d.%d.%d.%d"), dwIP&255, (dwIP>>8)&255, (dwIP>>16)&255, (dwIP>>24)&255);
}

int RMSHostEnt::GetIPArr(IPArr& iparr) const
{
	iparr = m_iparr;
	return m_iparr.size();
}

DWORD RMSHostEnt::GetLocalHostIP(int no)
{
	hostent* hi;
	char name[HOSTNAME_LEN];
	gethostname(name,HOSTNAME_LEN);
	hi= gethostbyname(name);
	if (hi==0) return 0;
	if (hi->h_addr_list[no]==0) return 0;
	return  *(DWORD*)(hi->h_addr_list[no]);
}
